package cn.edu.tju.wallet.domain;

import cn.edu.tju.core.model.BaseEntity;
import jakarta.persistence.*;
import java.math.BigDecimal;

/**
 * 透支规则实体（充血模型）
 * 包含透支规则数据和规则相关的业务逻辑
 */
@Entity
@Table(name = "overdraft_rules")
public class OverdraftRule extends BaseEntity {

    @Column(name = "name", nullable = false, length = 100)
    private String name; // 规则名称

    @Column(name = "min_vip_level", nullable = false)
    private Integer minVipLevel = 1; // 最小VIP等级

    @Column(name = "overdraft_limit", precision = 19, scale = 2, nullable = false)
    private BigDecimal overdraftLimit; // 透支限额

    @Column(name = "daily_interest_rate", precision = 8, scale = 6, nullable = false)
    private BigDecimal dailyInterestRate; // 每日利息率

    @Column(name = "grace_period_days", nullable = false)
    private Integer gracePeriodDays = 0; // 宽限期天数

    @Enumerated(EnumType.STRING)
    @Column(name = "status", nullable = false, length = 20)
    private RuleStatus status = RuleStatus.ACTIVE; // 规则状态

    @Column(name = "priority", nullable = false)
    private Integer priority = 0; // 优先级

    @Column(name = "comment", length = 500)
    private String comment; // 规则描述

    // ============================================
    // 构造函数
    // ============================================

    public OverdraftRule() {}

    public OverdraftRule(String name, Integer minVipLevel, BigDecimal overdraftLimit,
                        BigDecimal dailyInterestRate, Integer gracePeriodDays) {
        this.name = name;
        this.minVipLevel = minVipLevel;
        this.overdraftLimit = overdraftLimit;
        this.dailyInterestRate = dailyInterestRate;
        this.gracePeriodDays = gracePeriodDays;
        this.status = RuleStatus.ACTIVE;
        this.priority = 0;
    }

    public OverdraftRule(String name, Integer minVipLevel, BigDecimal overdraftLimit,
                        BigDecimal dailyInterestRate, Integer gracePeriodDays, String comment) {
        this.name = name;
        this.minVipLevel = minVipLevel;
        this.overdraftLimit = overdraftLimit;
        this.dailyInterestRate = dailyInterestRate;
        this.gracePeriodDays = gracePeriodDays;
        this.comment = comment;
        this.status = RuleStatus.ACTIVE;
        this.priority = 0;
    }

    // ============================================
    // 核心业务方法
    // ============================================

    /**
     * 判断用户是否符合透支条件（充血模型：规则自己判断用户是否符合条件）
     * @param vipLevel 用户VIP等级
     * @return 是否符合条件
     */
    public boolean isEligible(Integer vipLevel) {
        return this.status == RuleStatus.ACTIVE && vipLevel >= this.minVipLevel;
    }

    /**
     * 计算利息（充血模型：规则自己计算利息）
     * @param overdraftAmount 透支金额
     * @param days 透支天数
     * @return 利息金额
     */
    public BigDecimal calculateInterest(BigDecimal overdraftAmount, long days) {
        if (days <= this.gracePeriodDays) return BigDecimal.ZERO;

        long chargeableDays = days - this.gracePeriodDays;
        return overdraftAmount.multiply(this.dailyInterestRate)
                              .multiply(BigDecimal.valueOf(chargeableDays));
    }

    /**
     * 判断规则是否激活
     * @return 是否激活
     */
    public boolean isActive() {
        return this.status == RuleStatus.ACTIVE;
    }

    /**
     * 判断是否在宽限期内
     * @param days 透支天数
     * @return 是否在宽限期内
     */
    public boolean isWithinGracePeriod(long days) {
        return days <= this.gracePeriodDays;
    }

    /**
     * 判断用户是否可以透支指定金额
     * @param vipLevel 用户VIP等级
     * @param amount 想要透支的金额
     * @return 是否可以透支
     */
    public boolean canOverdraw(Integer vipLevel, BigDecimal amount) {
        return isEligible(vipLevel) && amount.compareTo(this.overdraftLimit) <= 0;
    }

    /**
     * 计算年利率
     * @return 年利率
     */
    public BigDecimal getAnnualInterestRate() {
        return this.dailyInterestRate.multiply(BigDecimal.valueOf(365))
                                    .multiply(BigDecimal.valueOf(100));
    }

    /**
     * 计算宽限期后的日利息
     * @param overdraftAmount 透支金额
     * @return 每日利息
     */
    public BigDecimal calculateDailyInterest(BigDecimal overdraftAmount) {
        return overdraftAmount.multiply(this.dailyInterestRate);
    }

    /**
     * 计算总还款额（透支金额 + 利息）
     * @param overdraftAmount 透支金额
     * @param days 透支天数
     * @return 总还款额
     */
    public BigDecimal calculateTotalRepayment(BigDecimal overdraftAmount, long days) {
        BigDecimal interest = calculateInterest(overdraftAmount, days);
        return overdraftAmount.add(interest);
    }

    /**
     * 计算透支成本（总还款额 - 透支金额）
     * @param overdraftAmount 透支金额
     * @param days 透支天数
     * @return 透支成本
     */
    public BigDecimal calculateOverdraftCost(BigDecimal overdraftAmount, long days) {
        return calculateInterest(overdraftAmount, days);
    }

    /**
     * 计算宽限期后的计息天数
     * @param totalDays 总透支天数
     * @return 计息天数
     */
    public long calculateChargeableDays(long totalDays) {
        return Math.max(0, totalDays - this.gracePeriodDays);
    }

    /**
     * 计算透支利率（百分比形式）
     * @return 年利率百分比
     */
    public BigDecimal getDailyInterestRatePercentage() {
        return this.dailyInterestRate.multiply(BigDecimal.valueOf(100));
    }

    /**
     * 获取透支规则描述
     * @return 规则描述
     */
    public String getOverdraftRuleDescription() {
        StringBuilder sb = new StringBuilder();
        sb.append("最低VIP等级: ").append(this.minVipLevel);
        sb.append("，透支限额: ").append(this.overdraftLimit).append("元");
        sb.append("，日利率: ").append(getDailyInterestRatePercentage()).append("%");
        sb.append("，宽限期: ").append(this.gracePeriodDays).append("天");
        return sb.toString();
    }

    /**
     * 激活规则
     * @return 当前规则对象
     */
    public OverdraftRule activate() {
        this.status = RuleStatus.ACTIVE;
        return this;
    }

    /**
     * 停用规则
     * @return 当前规则对象
     */
    public OverdraftRule deactivate() {
        this.status = RuleStatus.INACTIVE;
        return this;
    }

    /**
     * 设置透支参数
     * @param minVipLevel 最低VIP等级
     * @param overdraftLimit 透支限额
     * @param dailyInterestRate 日利率
     * @param gracePeriodDays 宽限期
     * @return 当前规则对象
     */
    public OverdraftRule setOverdraftParams(Integer minVipLevel, BigDecimal overdraftLimit,
                                          BigDecimal dailyInterestRate, Integer gracePeriodDays) {
        this.minVipLevel = minVipLevel;
        this.overdraftLimit = overdraftLimit;
        this.dailyInterestRate = dailyInterestRate;
        this.gracePeriodDays = gracePeriodDays;
        return this;
    }

    /**
     * 设置优先级
     * @param priority 优先级
     * @return 当前规则对象
     */
    public OverdraftRule setPriority(Integer priority) {
        this.priority = priority;
        return this;
    }

    /**
     * 验证规则参数的有效性
     * @throws IllegalArgumentException 当参数无效时
     */
    public void validate() {
        if (name == null || name.trim().isEmpty()) {
            throw new IllegalArgumentException("规则名称不能为空");
        }
        if (minVipLevel == null || minVipLevel < 0) {
            throw new IllegalArgumentException("最低VIP等级不能为负数");
        }
        if (overdraftLimit == null || overdraftLimit.compareTo(BigDecimal.ZERO) <= 0) {
            throw new IllegalArgumentException("透支限额必须大于0");
        }
        if (dailyInterestRate == null || dailyInterestRate.compareTo(BigDecimal.ZERO) < 0 ||
            dailyInterestRate.compareTo(BigDecimal.ONE) > 0) {
            throw new IllegalArgumentException("日利率必须在0到1之间");
        }
        if (gracePeriodDays == null || gracePeriodDays < 0) {
            throw new IllegalArgumentException("宽限期天数不能为负数");
        }
    }

    /**
     * 判断是否可以删除规则
     * @return 是否可以删除
     */
    public boolean canBeDeleted() {
        return this.status == RuleStatus.INACTIVE;
    }

    /**
     * 获取透支规则详细信息
     * @return 规则描述
     */
    public String getDescription() {
        if (comment != null && !comment.trim().isEmpty()) {
            return comment;
        }
        StringBuilder sb = new StringBuilder();
        sb.append(name).append("：");
        sb.append(getOverdraftRuleDescription());
        sb.append("，状态：").append(isActive() ? "激活" : "停用");
        return sb.toString();
    }

    /**
     * 判断是否免息（宽限期内的透支）
     * @param days 透支天数
     * @return 是否免息
     */
    public boolean isInterestFree(long days) {
        return isWithinGracePeriod(days);
    }

    /**
     * 计算当前等级可以享受的优惠利率（如果是阶梯利率结构）
     * @param vipLevel VIP等级
     * @return 适用的日利率
     */
    public BigDecimal getApplicableInterestRate(Integer vipLevel) {
        // 简化实现：所有等级使用统一利率
        // 实际中可以根据VIP等级返回不同利率
        return this.dailyInterestRate;
    }

    // ============================================
    // Getter and Setter
    // ============================================

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getMinVipLevel() {
        return minVipLevel;
    }

    public void setMinVipLevel(Integer minVipLevel) {
        this.minVipLevel = minVipLevel;
    }

    public BigDecimal getOverdraftLimit() {
        return overdraftLimit;
    }

    public void setOverdraftLimit(BigDecimal overdraftLimit) {
        this.overdraftLimit = overdraftLimit;
    }

    public BigDecimal getDailyInterestRate() {
        return dailyInterestRate;
    }

    public void setDailyInterestRate(BigDecimal dailyInterestRate) {
        this.dailyInterestRate = dailyInterestRate;
    }

    public Integer getGracePeriodDays() {
        return gracePeriodDays;
    }

    public void setGracePeriodDays(Integer gracePeriodDays) {
        this.gracePeriodDays = gracePeriodDays;
    }

    public RuleStatus getStatus() {
        return status;
    }

    public void setStatus(RuleStatus status) {
        this.status = status;
    }

    public String getComment() {
        return comment;
    }

    public void setComment(String comment) {
        this.comment = comment;
    }


    // 规则状态
    public enum RuleStatus {
        ACTIVE,     // 激活
        INACTIVE    // 未激活
    }
}

